package com.luo.ai.mcp.server.resources;

import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.McpSyncServerExchange;
import io.modelcontextprotocol.spec.McpSchema;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.util.List;

/**
 * 我的基础资源
 *
 * @author luohq
 * @date 2025-04-27 14:30
 */
public interface MyBaseResource {
    /**
     * 生成资源描述
     *
     * @return 资源描述
     */
    McpSchema.Resource resourceDesc();

    /**
     * 返回资源内容
     *
     * @return 资源内容
     */
    Object resourceContent();

    /**
     * 是否异步资源（默认同步）
     *
     * @return 是否异步资源
     */
    default Boolean isAsync() {
        return false;
    }

    /**
     * 构建同步资源
     *
     * @return 同步资源
     */
    default McpServerFeatures.SyncResourceSpecification buildSyncResource() {
        return this.buildSyncTextResource();
    }

    /**
     * 构建异步资源
     *
     * @return 同步资源
     * @see McpServerFeatures.AsyncResourceSpecification#fromSync(McpServerFeatures.SyncResourceSpecification)
     */
    default McpServerFeatures.AsyncResourceSpecification buildAsyncResource() {
        McpServerFeatures.SyncResourceSpecification syncResourceSpecification = this.buildSyncResource();
        if (syncResourceSpecification == null) {
            return null;
        }
        return new McpServerFeatures.AsyncResourceSpecification(syncResourceSpecification.resource(),
                (exchange, req) -> Mono
                        .fromCallable(() -> syncResourceSpecification.readHandler().apply(new McpSyncServerExchange(exchange), req))
                        .subscribeOn(Schedulers.boundedElastic()));
    }

    /**
     * 构建同步文本资源
     *
     * @return 同步文本资源
     */
    default McpServerFeatures.SyncResourceSpecification buildSyncTextResource() {
        //资源说明
        McpSchema.Resource resourceDesc = this.resourceDesc();
        Object resourceContent = this.resourceContent();
        String resourceTextContent = String.valueOf(resourceContent);
        McpServerFeatures.SyncResourceSpecification resourceSpecification = new McpServerFeatures.SyncResourceSpecification(
                resourceDesc,
                (exchange, request) -> {
                    return new McpSchema.ReadResourceResult(List.of(
                            new McpSchema.TextResourceContents(request.uri(), resourceDesc.mimeType(), resourceTextContent)
                    ));
                });
        return resourceSpecification;
    }

}
